package com.zeyu.framework.tools.param.web;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zeyu.framework.core.common.mapper.JsonMapper;
import com.zeyu.framework.core.persistence.Page;
import com.zeyu.framework.core.persistence.entity.BaseEntity;
import com.zeyu.framework.core.web.BaseController;
import com.zeyu.framework.core.web.Result;
import com.zeyu.framework.tools.param.entity.Param;
import com.zeyu.framework.tools.param.service.ParamService;
import com.zeyu.framework.tools.param.utils.ParamUtils;
import com.zeyu.framework.utils.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 参数Controller
 */
@Controller
@RequestMapping(value = "/tools/param")
public class ParamController extends BaseController {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    @Autowired
    private ParamService paramService;

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    /**
     * 注解 @ModelAttribute 注释的方法会在此controller每个方法执行前被执行
     */
    @ModelAttribute
    public Param get(@RequestParam(required = false) String id) {
        if (StringUtils.isNotBlank(id)) {
            return paramService.get(id);
        } else {
            return new Param();
        }
    }

    /**
     * 参数列表页
     */
    @RequiresPermissions("tools:param:view")
    @RequestMapping(value = {"", "index"})
    public String index() {
        return "modules/tools/paramIndex";
    }

    /**
     * 参数表单页
     */
    @RequiresPermissions("tools:param:view")
    @RequestMapping(value = "form")
    public String form(String id, String parentId, Model model) {
        if (StringUtils.isNotBlank(id) && !StringUtils.endsWithIgnoreCase("-999", id)) {
            //  获取指定的group和name的信息
            model.addAttribute("entity", JsonMapper.toJsonString(paramService.get(id)));
        } else {
            Param param = new Param();
            param.setParent(paramService.get(parentId));
            param.setParentName(param.getParent().getLabel());
            model.addAttribute("entity", JsonMapper.toJsonString(param));
        }
        return "modules/tools/paramForm";
    }

    /**
     * 任务列表页
     */
    @RequiresPermissions("tools:param:view")
    @RequestMapping(value = "table")
    public String table(String id, Model model) {
        model.addAttribute("id", id);
        return "modules/tools/paramList";
    }

    /**
     * 获取参数列表
     */
    @RequiresPermissions("tools:param:view")
    @RequestMapping(value = "list")
    @ResponseBody
    public Page<Param> list(HttpServletRequest request) {
        Page<Param> page = new Page<>(request);
        // 查询扩展
        String extraSearch = page.getDatatablesCriterias().getExtraSearch();
        // 转换
        Param param = JsonMapper.getInstance().fromJson(extraSearch, Param.class);
        if (param == null) {
            param = new Param();
        }
        page.setCount(1);
        if (param.getId() == null) {
            page.setList(ParamUtils.getChildParamList(Param.DEFAULT_ROOT_ID));
        } else {
            page.setList(ParamUtils.getChildParamList(param.getId()));
        }

        return page;
    }

    /**
     * 获取参数树
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "treeData")
    public List<Map<String, Object>> treeData(String id) {
        List<Map<String, Object>> mapList = Lists.newArrayList();
        List<Param> list;
        if (StringUtils.isBlank(id)) {
            list = paramService.findList(new Param());
            // 设置一个隐藏节点,新增跳转时使用
            Map<String, Object> hiddenNode = Maps.newHashMap();
            hiddenNode.put("id", "-999");
            hiddenNode.put("name", "hidden");
            hiddenNode.put("type", Param.PARAM_TYPE_INFO);
            hiddenNode.put("isHidden", true);

            mapList.add(hiddenNode);
        } else {
            list = ParamUtils.getChildParamList(id);
        }
        list.stream().filter(e -> e.getName() != null)
                .forEach(e -> {
                    Map<String, Object> map = Maps.newHashMap();
                    map.put("id", e.getId());
                    map.put("pId", e.getParentId());
                    map.put("pIds", e.getParentIds());
                    String color = e.getFixed() == 0 ? " " : " text-danger";
                    String oname = "<i class='" + ParamUtils.getIconByType(e) + color + "'></i> " + StringUtils.replace(e.getLabel(), " ", "");
                    map.put("name", oname);
                    map.put("type", e.getType());
                    if (StringUtils.equals(e.getType(), "0") || StringUtils.equals(e.getType(), "1") || StringUtils.equals(e.getType(), "2")) {
                        map.put("isParent", true);
                    } else {
                        map.put("isParent", false);
                    }

                    mapList.add(map);
                });

        return mapList;
    }

    /**
     * 更新参数
     */
    @RequiresPermissions("tools:param:edit")
    @RequestMapping(value = "save")
    @ResponseBody
    public Result save(@Validated Param param) {
        Result result = new Result();
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        if (StringUtils.isNoneBlank(param.getId())) {
            // 更新操作,判断是否fixed
            if (param.getFixed() == BaseEntity.FIX_FLAG_YES) {
                result.setStatus(Result.ERROR);
                result.setMessage("参数是锁定项目，不允许更新操作!");
                return result;
            }
        }
        paramService.save(param);
        result.setStatus(Result.SUCCESS);
        result.setMessage("保存参数'" + param.getLabel() + "'成功");

        return result;
    }

    /**
     * 删除参数
     */
    @RequiresPermissions("tools:param:edit")
    @RequestMapping(value = "delete")
    @ResponseBody
    public Result delete(Param param) {
        Result result = new Result();
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        paramService.delete(param);
        result.setStatus(Result.SUCCESS);
        result.setMessage("删除参数成功");
        return result;
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================
}
